#include "Input.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

// 输入通道配置数组
Input_Channel_t InputChannels[] = {
    {GPIOE, GPIO_Pin_10, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},
    {GPIOE, GPIO_Pin_11, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},
    {GPIOE, GPIO_Pin_12, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},
    {GPIOE, GPIO_Pin_13, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},
    {GPIOE, GPIO_Pin_14, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},
    {GPIOE, GPIO_Pin_15, INPUT_ACTIVE_LOW, GPIO_Mode_IPU, 0, 0, 0, 0, 0},

};

// 获取输入通道数量
#define INPUT_COUNT (sizeof(InputChannels) / sizeof(Input_Channel_t))
static uint16_t act_count[INPUT_COUNT];

// 输入初始化函数
void Input_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 初始化所有输入通道
    for (uint8_t i = 0; i < INPUT_COUNT; i++) {
        Input_Channel_t* channel = &InputChannels[i];

        // 使能对应GPIO端口的时钟
        if (channel->GPIOx == GPIOA) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        } else if (channel->GPIOx == GPIOB) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        } else if (channel->GPIOx == GPIOC) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        } else if (channel->GPIOx == GPIOD) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
        } else if (channel->GPIOx == GPIOE) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
        }

        // 配置GPIO为指定输入模式
        GPIO_InitStructure.GPIO_Pin   = channel->GPIO_Pin;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = channel->mode;

        GPIO_Init(channel->GPIOx, &GPIO_InitStructure);
    }
}

// 输入状态读取函数
uint8_t Input_Read(uint8_t channel) {
    if (channel >= INPUT_COUNT) {
        return INPUT_STATE_ERROR;   // 通道检查
    }

    Input_Channel_t* input    = &InputChannels[channel];
    uint8_t          pinState = GPIO_ReadInputDataBit(input->GPIOx, input->GPIO_Pin);

    // 根据有效电平返回对应状态
    if ((input->activeLevel == INPUT_ACTIVE_HIGH && pinState == Bit_SET) ||
        (input->activeLevel == INPUT_ACTIVE_LOW && pinState == Bit_RESET)) {
        return INPUT_STATE_ACTIVE;
    } else {
        return INPUT_STATE_INACTIVE;
    }
}
// 数字输入状态更新（TIM4中调用）
void DIN_Proc(void) {
    static int time_count = 0;
    if (time_count++ < REFTIME) {
        return;
    }
    time_count = 0;

    for (uint8_t i = 0; i < INPUT_COUNT; i++) {   // 状态
        Input_Channel_t* channel   = &InputChannels[i];
        uint8_t          cur_state = Input_Read(i);

        if (cur_state == INPUT_STATE_INACTIVE) {
            channel->close_time++;
            channel->open_time = 0;

            if (channel->close_time >= INPUT_SHAKE_MUN) {
                channel->close_time = INPUT_SHAKE_MUN;
                channel->state      = INPUT_STATE_INACTIVE;
            }
        } else {
            channel->open_time++;
            channel->close_time = 0;

            if (channel->open_time >= INPUT_SHAKE_MUN) {
                channel->open_time = INPUT_SHAKE_MUN;
                channel->state     = INPUT_STATE_ACTIVE;
            }
        }
    }
    for (int i = 0; i < INPUT_COUNT; i++) {   // 脉冲
        Input_Channel_t* channel = &InputChannels[i];
        if (channel->state == INPUT_STATE_ACTIVE) {
            channel->pulse_time++;
        } else {
            if (channel->pulse_time > PULSE_TIME) {
                channel->pulse_count++;
            }

            channel->pulse_time = 0;
        }
    }
    for (int i = 0; i < INPUT_COUNT; i++) {   // 吸合计时

        Input_Channel_t* channel = &InputChannels[i];

        if (channel->state == INPUT_STATE_ACTIVE) {
            act_count[i]++;
        } else {
            act_count[i] = 0;
        }
        if (act_count[i] >= ACTIVETIME) {
            channel->active_time++;
            act_count[i] = 0;
        }
    }
}
// 获取稳定状态函数
uint8_t Get_input_state(uint8_t channel) {
    if (channel >= INPUT_COUNT) {
        return INPUT_STATE_ERROR;
    }
    return InputChannels[channel].state;
}

// 获取脉冲个数
uint8_t Get_pulse_count(uint8_t channel) {
    if (channel >= INPUT_COUNT) {
        return INPUT_STATE_ERROR;
    }
    return InputChannels[channel].pulse_count;
}

uint16_t Get_active_time(uint8_t channel) {
    if (channel >= INPUT_COUNT) {
        return INPUT_STATE_ERROR;
    }
    return InputChannels[channel].active_time;
}
